home *** CD-ROM | disk | FTP | other *** search
- //DASHANIM.CPP-- Methods file for routines that play .DSH animation files
- // created by PCX2DSH.
- // (C) 1995 Eric M. Dashofy / Archon Software
- // All Rights Reserved
-
- //Note: Must be cross-compiled with XMM.CPP
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <dos.h>
- #include <conio.h>
- #include "xmm.h"
- #include "dashanim.h"
-
- word dsh_flood_buffer(buf_struct& buffer){
- long position = ftell(buffer.file);
- long filelen = buffer.hdr.FileLength;
- word bytes_to_read = buf_size;
- if ((filelen - position) < buffer.buf_size){
- bytes_to_read = (filelen - position);
- }
- fread(buffer.buf_ptr, sizeof(byte), bytes_to_read, buffer.file);
- buffer.bytes_read = bytes_to_read;
- buffer.offset = 0;
- return bytes_to_read;
- }
-
- void dsh_get_header(FILE* stream, DSH_Header& hdr){
- fread(&hdr, sizeof(hdr), 1, stream);
- }
-
- word dsh_xms_flood_buffer(DashXMM& AnimXMS, buf_struct& buffer){
- word bytes_to_read = buf_size;
- if ((buffer.hdr.FileLength - AnimXMS.index) < buffer.buf_size){
- bytes_to_read = (buffer.hdr.FileLength - AnimXMS.index);
- }
- AnimXMS.move(bytes_to_read, (void far*) buffer.buf_ptr, AnimXMS.index);
- buffer.bytes_read = bytes_to_read;
- buffer.offset = 0;
- AnimXMS.index += bytes_to_read;
- return bytes_to_read;
- }
-
- void dsh_get_bytes(byte far* to, word num_bytes, buf_struct& buffer,
- DashXMM& AnimXMS){
- word btm = 0;
- word to_offset = 0;
- /*
- while (bytes_copied < num_bytes){
- if ((buffer.bytes_read == buffer.offset))
- dsh_xms_flood_buffer(AnimXMS, buffer);
- to[bytes_copied] = buffer.buf_ptr[buffer.offset];
- bytes_copied++;
- buffer.offset++;
- }
- */
- if (buffer.offset == buffer.bytes_read)
- dsh_xms_flood_buffer(AnimXMS, buffer); //flood the buffer
-
-
- btm = num_bytes; //move all bytes;
- while((buffer.offset + btm) > buffer.bytes_read){
- if ((buffer.offset + btm) > buffer.bytes_read){
- //if we will go past the end of the buffer, copy to end first
- btm = buffer.bytes_read - buffer.offset; //bytes to read = rest of buffer
- memcpy((void far*)&to[to_offset], (void far*)&buffer.buf_ptr[buffer.offset],
- btm);
- to_offset += btm; //inc. to_offset for rest of move
- btm = num_bytes - btm; //set rest of bytes to move
- dsh_xms_flood_buffer(AnimXMS, buffer); //flood the buffer
- }
- }
-
- memcpy((void far*)&to[to_offset], (void far*)&buffer.buf_ptr[buffer.offset],
- btm); //move bytes (rest of bytes if already did some)
- buffer.offset += btm;
- }
-
-
- void set_palette(byte* pal){
- /*
- _AH = 0x10;
- _AL = 0x12;
- _BX = 0;
- _CX = 0x100;
- _ES = FP_SEG(pal);
- _DX = FP_OFF(pal);
- geninterrupt(0x10);
- */
- int port1 = 0x3c8;
- int port2 = 0x3c9;
- char nullchar='\0';
- outportb(port1,nullchar); //initialize EGA/VGA to read 768 palette regs
-
- for (short i=0; i<768; i++){
- outportb(port2,pal[i]);
- }
- }
-
- void setmode(byte mode){
- //_AL = mode;
- //_AH = 0;
- //geninterrupt(0x10);
- asm{
- mov al, mode
- mov ah, 0
- int 10h
- }
- }
-
- int playdsh(char* afn, unsigned int delayms){
- DashXMM AnimXMS (FALSE); //open xms for animation, no swapfile, not verbose
-
- //this program's purpose is to play a .DSH animation file quickly.
-
- //we're going to forego the details and do this one:
-
- int oldmode=*(int *)MK_FP(0x40,0x49); // Set VGA mode...
- setmode(0x13); // to 320x200x256
-
- FILE* DashFile;
- if ((DashFile = fopen(afn, "rb")) == NULL){
- setmode (oldmode);
- fprintf(stderr, "Cannot open %s.\n", afn);
-
- return 1;
- }
- DSH_Header hdr;
- dsh_get_header (DashFile, hdr);
-
- //now, with the header, we can allocate the proper amount of XMS with the
- //filesize contained therein
-
- AnimXMS.allocate(hdr.FileLength + 20);
- AnimXMS.index = sizeof(hdr);
-
- //set the buffer
- buf_struct buffer;
- buffer.file = DashFile;
- buffer.buf_size = buf_size;
- buffer.hdr = hdr;
- buffer.bytes_read = 0;
- buffer.offset = 0;
- buffer.buf_ptr = new byte[buf_size]; //allocate
- if (buffer.buf_ptr == NULL){
- setmode(oldmode);
- printf("\nSorry, not enough memory to allocate buffer!\n");
- return 1;
- }
-
- //this buffer will now be used, briefly, to buffer the input file into XMS
- fseek(DashFile, 0, 0); //reset the file
- dword bytes_to_read = hdr.FileLength;
- dword bytes_to_move = 0;
- boolean move_complete = FALSE;
- dword xms_offset = 0;
- do{
- bytes_to_move = buf_size;
- if (bytes_to_move > bytes_to_read){
- bytes_to_move = bytes_to_read;
- move_complete = TRUE;
- }
- fread(buffer.buf_ptr, 1, bytes_to_move, DashFile);
- AnimXMS.move(bytes_to_move, xms_offset, (void far*)buffer.buf_ptr);
- bytes_to_read -= bytes_to_move;
- xms_offset += bytes_to_move;
- }while(!move_complete);
- //there. The input file is now completely in XMS.
-
- //go on
- byte far* ScreenPtr = (byte far*)MK_FP(0xA000, 0);
- word ScreenOffset = 0;
- byte Palette[768];
-
- byte br;
- byte curmode;
- word wr;
- byte* p_wr = &((byte)wr);
- dword dwr;
-
- dsh_get_bytes(&br, 1, buffer, AnimXMS); //should be 0xFF - NewFrame
-
- dsh_get_bytes(Palette, 768, buffer, AnimXMS);
- set_palette(Palette);
- dsh_get_bytes(ScreenPtr, 64000U, buffer, AnimXMS);
-
- int i = 0;
- for (i = 1; i < hdr.NumFrames; i++){
- ScreenOffset = 0;
- dsh_get_bytes(&br, 1, buffer, AnimXMS); //should be 0xFF - NewFrame
- if (delayms > 0) delay(delayms);
- //reintroduce next line for debugging
- //if (br != NewFrame) break;
- dsh_get_bytes(Palette, 768, buffer, AnimXMS); //get frame palette
- set_palette(Palette); //set frame palette
- do{
- dsh_get_bytes(&curmode, 1, buffer, AnimXMS); //get mode
- if (curmode == SkipMode){
- dsh_get_bytes(p_wr, 2, buffer, AnimXMS); //get # to skip
- ScreenOffset += (wr); //skip bytes
- }
- if (curmode == WriteMode){
- dsh_get_bytes(p_wr, 2, buffer, AnimXMS); //get # to write
- dsh_get_bytes(ScreenPtr + ScreenOffset, wr, buffer, AnimXMS);
- //Write 'em
- ScreenOffset += (wr);
- }
- //reintroduce next line for debugging
- //if ((curmode != SkipMode) && (curmode != WriteMode)) break;
- }while (ScreenOffset != 63999U);
- }
-
- fclose(DashFile);
- AnimXMS.free();
- delete buffer.buf_ptr;
- setmode(oldmode);
- return 0;
-
- }
-